<!DOCTYPE html>
<html lang="en" class="js csstransforms3d">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <meta name="generator" content="Hugo 0.20.7" />
    <meta name="description" content="">


    <link rel="shortcut icon" href="http://shardingjdbc.io/document/legacy/2.x/cn/img/favicon.png" type="image/x-icon" />

    
    <title>分布式主键</title>
    <link href="http://ovfotjrsi.bkt.clouddn.com/docs/css/nucleus.css" rel="stylesheet">
    <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
    <link href="http://ovfotjrsi.bkt.clouddn.com/docs/css/theme.css" rel="stylesheet">
    <link href="http://ovfotjrsi.bkt.clouddn.com/docs/css/hugo-theme.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
    <style type="text/css">:root #header + #content > #left > #rlblock_left
    {display:none !important;}</style>
    <link rel="stylesheet" href="http://cdn.bootcss.com/highlight.js/9.8.0/styles/monokai-sublime.min.css">
<link rel="stylesheet" href="http://ovfotjrsi.bkt.clouddn.com/docs/css/style.css">
  </head>
  <body class="" data-url="/02-guide/key-generator/">
    
    <nav id="sidebar">
  <div id="header-wrapper">
    <div id="header">
      <img src="http://ovfotjrsi.bkt.clouddn.com/docs/img/sharding-jdbc.png" />
    </div>
</div>
  <div class="highlightable">
    <ul class="topics">
      
        
        
          
          
            
          
        
          
          
            
          
        
          
          
            
          
        
          
          
            
          
        
        
        
          
        
          
        
          
        
          
        
      
      
      
      

      
      
      
        
          
          
            
          
        
      
      
      

      <li class="dd-item  " data-nav-id="/00-overview/">
        <a href="http://shardingjdbc.io/document/legacy/2.x/cn/00-overview/">
          <span>
            
              <b>0. </b>
            
             概览
            
           </span>
        </a>
        
        <ul>
          
            <li class="dd-item " data-nav-id="/00-overview/intro/">
              <a href="http://shardingjdbc.io/document/legacy/2.x/cn/00-overview/intro/">
                <span>简介     </i></span>
              </a>
            </li>
          
            <li class="dd-item " data-nav-id="/00-overview/news/">
              <a href="http://shardingjdbc.io/document/legacy/2.x/cn/00-overview/news/">
                <span>新闻     </i></span>
              </a>
            </li>
          
            <li class="dd-item " data-nav-id="/00-overview/contribution/">
              <a href="http://shardingjdbc.io/document/legacy/2.x/cn/00-overview/contribution/">
                <span>贡献代码     </i></span>
              </a>
            </li>
          
        </ul>
        
      </li>
      
      
      

      
      
      
        
          
          
            
          
        
      
      
      

      <li class="dd-item  " data-nav-id="/01-start/">
        <a href="http://shardingjdbc.io/document/legacy/2.x/cn/01-start/">
          <span>
            
              <b>1. </b>
            
             起航
            
           </span>
        </a>
        
        <ul>
          
            <li class="dd-item " data-nav-id="/01-start/quick-start/">
              <a href="http://shardingjdbc.io/document/legacy/2.x/cn/01-start/quick-start/">
                <span>快速入门     </i></span>
              </a>
            </li>
          
            <li class="dd-item " data-nav-id="/01-start/code-demo/">
              <a href="http://shardingjdbc.io/document/legacy/2.x/cn/01-start/code-demo/">
                <span>使用示例     </i></span>
              </a>
            </li>
          
            <li class="dd-item " data-nav-id="/01-start/faq/">
              <a href="http://shardingjdbc.io/document/legacy/2.x/cn/01-start/faq/">
                <span>FAQ     </i></span>
              </a>
            </li>
          
            <li class="dd-item " data-nav-id="/01-start/features/">
              <a href="http://shardingjdbc.io/document/legacy/2.x/cn/01-start/features/">
                <span>详细功能列表     </i></span>
              </a>
            </li>
          
            <li class="dd-item " data-nav-id="/01-start/limitations/">
              <a href="http://shardingjdbc.io/document/legacy/2.x/cn/01-start/limitations/">
                <span>使用限制     </i></span>
              </a>
            </li>
          
            <li class="dd-item " data-nav-id="/01-start/sql-supported/">
              <a href="http://shardingjdbc.io/document/legacy/2.x/cn/01-start/sql-supported/">
                <span>SQL支持详细列表     </i></span>
              </a>
            </li>
          
            <li class="dd-item " data-nav-id="/01-start/stress-test/">
              <a href="http://shardingjdbc.io/document/legacy/2.x/cn/01-start/stress-test/">
                <span>性能测试报告     </i></span>
              </a>
            </li>
          
        </ul>
        
      </li>
      
      
      

      
      
      
        
          
          
            
          
        
      
      
      

      <li class="dd-item  parent" data-nav-id="/02-guide/">
        <a href="http://shardingjdbc.io/document/legacy/2.x/cn/02-guide/">
          <span>
            
              <b>2. </b>
            
             使用指南
            
           </span>
        </a>
        
        <ul>
          
            <li class="dd-item " data-nav-id="/02-guide/concepts/">
              <a href="http://shardingjdbc.io/document/legacy/2.x/cn/02-guide/concepts/">
                <span>核心概念     </i></span>
              </a>
            </li>
          
            <li class="dd-item " data-nav-id="/02-guide/sharding/">
              <a href="http://shardingjdbc.io/document/legacy/2.x/cn/02-guide/sharding/">
                <span>分库分表     </i></span>
              </a>
            </li>
          
            <li class="dd-item " data-nav-id="/02-guide/master-slave/">
              <a href="http://shardingjdbc.io/document/legacy/2.x/cn/02-guide/master-slave/">
                <span>读写分离     </i></span>
              </a>
            </li>
          
            <li class="dd-item " data-nav-id="/02-guide/config_domain/">
              <a href="http://shardingjdbc.io/document/legacy/2.x/cn/02-guide/config_domain/">
                <span>配置域模型     </i></span>
              </a>
            </li>
          
            <li class="dd-item " data-nav-id="/02-guide/configuration/">
              <a href="http://shardingjdbc.io/document/legacy/2.x/cn/02-guide/configuration/">
                <span>配置手册     </i></span>
              </a>
            </li>
          
            <li class="dd-item " data-nav-id="/02-guide/orchestration/">
              <a href="http://shardingjdbc.io/document/legacy/2.x/cn/02-guide/orchestration/">
                <span>编排治理     </i></span>
              </a>
            </li>
          
            <li class="dd-item " data-nav-id="/02-guide/hint-sharding-value/">
              <a href="http://shardingjdbc.io/document/legacy/2.x/cn/02-guide/hint-sharding-value/">
                <span>强制路由     </i></span>
              </a>
            </li>
          
            <li class="dd-item active" data-nav-id="/02-guide/key-generator/">
              <a href="http://shardingjdbc.io/document/legacy/2.x/cn/02-guide/key-generator/">
                <span>分布式主键     </i></span>
              </a>
            </li>
          
            <li class="dd-item " data-nav-id="/02-guide/transaction/">
              <a href="http://shardingjdbc.io/document/legacy/2.x/cn/02-guide/transaction/">
                <span>事务支持     </i></span>
              </a>
            </li>
          
            <li class="dd-item " data-nav-id="/02-guide/subquery/">
              <a href="http://shardingjdbc.io/document/legacy/2.x/cn/02-guide/subquery/">
                <span>分页及子查询     </i></span>
              </a>
            </li>
          
            <li class="dd-item " data-nav-id="/02-guide/test-framework/">
              <a href="http://shardingjdbc.io/document/legacy/2.x/cn/02-guide/test-framework/">
                <span>测试引擎     </i></span>
              </a>
            </li>
          
            <li class="dd-item " data-nav-id="/02-guide/apm/">
              <a href="http://shardingjdbc.io/document/legacy/2.x/cn/02-guide/apm/">
                <span>应用性能监控     </i></span>
              </a>
            </li>
          
            <li class="dd-item " data-nav-id="/02-guide/sharding-jdbc-server/">
              <a href="http://shardingjdbc.io/document/legacy/2.x/cn/02-guide/sharding-jdbc-server/">
                <span>Sharding-JDBC-Server     </i></span>
              </a>
            </li>
          
        </ul>
        
      </li>
      
      
      

      
      
      
        
          
          
            
          
        
      
      
      

      <li class="dd-item  " data-nav-id="/03-design/">
        <a href="http://shardingjdbc.io/document/legacy/2.x/cn/03-design/">
          <span>
            
              <b>3. </b>
            
             设计规划
            
           </span>
        </a>
        
        <ul>
          
            <li class="dd-item " data-nav-id="/03-design/architecture/">
              <a href="http://shardingjdbc.io/document/legacy/2.x/cn/03-design/architecture/">
                <span>架构设计     </i></span>
              </a>
            </li>
          
            <li class="dd-item " data-nav-id="/03-design/module/">
              <a href="http://shardingjdbc.io/document/legacy/2.x/cn/03-design/module/">
                <span>模块说明     </i></span>
              </a>
            </li>
          
            <li class="dd-item " data-nav-id="/03-design/roadmap/">
              <a href="http://shardingjdbc.io/document/legacy/2.x/cn/03-design/roadmap/">
                <span>未来线路规划     </i></span>
              </a>
            </li>
          
        </ul>
        
      </li>
      
      
    </ul>
    <hr>
     
  </div>
</nav>

        <section id="body">
        <div id="overlay"></div>

        <div class="padding highlightable">

            <div id="top-bar">
              
              <div id="breadcrumbs" itemscope="" itemtype="http://data-vocabulary.org/Breadcrumb">
                  <span id="sidebar-toggle-span">
                      <a href="#" id="sidebar-toggle" data-sidebar-toggle="">
                        <i class="fa fa-bars"></i>
                      </a>
                  </span>
                
                <span id="toc-menu"><a href=""><i class="fa fa-list-alt"></i></a></span>
                
                
                  
                  
                  
                    
                    
                <a href="http://shardingjdbc.io/document/legacy/2.x/cn/02-guide/" itemprop="url"><span itemprop="title">使用指南</span></a> <i class="fa fa-angle-right"></i>
                    
                  
                
                <span itemprop="title"> 分布式主键</span>
              </div>
              
                  <div class="progress">
    <div class="wrapper">
<nav id="TableOfContents">
<ul>
<li>
<ul>
<li><a href="#实现动机">实现动机</a></li>
<li><a href="#使用方法">使用方法</a>
<ul>
<li><a href="#设置自动生成键">设置自动生成键</a></li>
<li><a href="#获取自动生成键">获取自动生成键</a></li>
<li><a href="#其他框架配置">其他框架配置</a></li>
</ul></li>
</ul></li>
<li><a href="#默认的分布式主键生成器">默认的分布式主键生成器</a>
<ul>
<li>
<ul>
<li><a href="#时间位-41bit">时间位(41bit)</a></li>
<li><a href="#工作进程位-10bit">工作进程位(10bit)</a></li>
<li><a href="#序列位-12bit">序列位(12bit)</a></li>
<li><a href="#总结">总结</a></li>
</ul></li>
</ul></li>
</ul>
</nav>
    </div>
</div>

              

            </div>
            
              <div id="body-inner">
                
                <h1>分布式主键</h1>
                



<h2 id="实现动机">实现动机</h2>

<p>传统数据库软件开发中，主键自动生成技术是基本需求。而各大数据库对于该需求也提供了相应的支持，比如MySQL的自增键。
对于MySQL而言，分库分表之后，不同表生成全局唯一的Id是非常棘手的问题。因为同一个逻辑表内的不同实际表之间的自增键是无法互相感知的，
这样会造成重复Id的生成。我们当然可以通过约束表生成键的规则来达到数据的不重复，但是这需要引入额外的运维力量来解决重复性问题，并使框架缺乏扩展性。</p>

<p>目前有许多第三方解决方案可以完美解决这个问题，比如UUID等依靠特定算法自生成不重复键，或者通过引入Id生成服务等。
但也正因为这种多样性导致了Sharding-JDBC如果强依赖于任何一种方案就会限制其自身的发展。</p>

<p>基于以上的原因，最终采用了以JDBC接口来实现对于生成Id的访问，而将底层具体的Id生成实现分离出来。</p>

<h2 id="使用方法">使用方法</h2>

<p>使用方法分为设置自动生成键和获取生成键两部分</p>

<h3 id="设置自动生成键">设置自动生成键</h3>

<p>配置自增列：</p>

<pre><code class="language-java">TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration();
tableRuleConfig.setLogicTable(&quot;t_order&quot;);
tableRuleConfig.setKeyGeneratorColumnName(&quot;order_id&quot;);
</code></pre>

<p>设置Id生成器的实现类，该类必须实现io.shardingjdbc.core.keygen.KeyGenerator接口。</p>

<p>配置全局生成器(com.xx.xx.KeyGenerator):</p>

<pre><code class="language-java">ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
shardingRuleConfig.setDefaultKeyGeneratorClass(&quot;com.xx.xx.KeyGenerator&quot;);
</code></pre>

<p>有时候我们希望部分表的Id生成器与全局Id生成器不同，比如t_order_item表希望使用com.xx.xx.OtherKeyGenerator来生成Id:</p>

<pre><code class="language-java">TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration();
tableRuleConfig.setLogicTable(&quot;t_order&quot;);
tableRuleConfig.setKeyGeneratorColumnName(&quot;order_id&quot;);
tableRuleConfig.setKeyGeneratorClass(&quot;com.xx.xx.OtherKeyGenerator&quot;);
</code></pre>

<p>这样t_order就使用com.xx.xx.KeyGenerator生成Id，而t_order_item使用com.xx.xx.OtherKeyGenerator生成Id。</p>

<h3 id="获取自动生成键">获取自动生成键</h3>

<p>通过JDBC提供的API来获取。对于Statement来说调用<code>statement.execute(&quot;INSERT ...&quot;, Statement.RETURN_GENERATED_KEYS)</code>
来通知需要返回的生成的键值。对于PreparedStatement则是<code>connection.prepareStatement(&quot;INSERT ...&quot;, Statement.RETURN_GENERATED_KEYS)</code></p>

<p>调用<code>statement.getGeneratedKeys()</code>来获取键值的ResultSet。</p>

<h3 id="其他框架配置">其他框架配置</h3>

<p>关于Spring，YAML，MyBatis和JPA（Hibernate）的配置请参考
<a href="https://github.com/shardingjdbc/sharding-jdbc/tree/master/sharding-jdbc-example">示例工程</a>。</p>

<h1 id="默认的分布式主键生成器">默认的分布式主键生成器</h1>

<p>类名称：io.shardingjdbc.core.keygen.DefaultKeyGenerator</p>

<p>该生成器采用snowflake算法实现，生成的数据为64bit的long型数据。
在数据库中应该用大于等于64bit的数字类型的字段来保存该值，比如在MySQL中应该使用BIGINT。</p>

<p>其二进制表示形式包含四部分，从高位到低位分表为：1bit符号位(为0)，41bit时间位，10bit工作进程位，12bit序列位。</p>

<h3 id="时间位-41bit">时间位(41bit)</h3>

<p>从2016年11月1日零点到现在的毫秒数，时间可以使用到2156年，满足大部分系统的要求。</p>

<h3 id="工作进程位-10bit">工作进程位(10bit)</h3>

<p>该标志在Java进程内是唯一的，如果是分布式应用部署应保证每个进程的工作进程Id是不同的。该值默认为0，可通过调用静态方法<code>DefaultKeyGenerator.setWorkerId(&quot;xxxx&quot;)</code>设置。</p>

<h3 id="序列位-12bit">序列位(12bit)</h3>

<p>该序列是用来在同一个毫秒内生成不同的Id。如果在这个毫秒内生成的数量超过4096(2的12次方)，那么生成器会等待到下个毫秒继续生成。</p>

<h3 id="总结">总结</h3>

<p>从Id的组成部分看，不同进程的Id肯定是不同的，同一个进程首先是通过时间位保证不重复，如果时间相同则是通过序列位保证。
同时由于时间位是单调递增的，且各个服务器如果大体做了时间同步，那么生成的Id在分布式环境可以认为是总体有序的。
这就保证了对索引字段的插入的高效性。例如MySQL的Innodb存储引擎的主键。</p>


      
      
      </div>
    </div>

    

    <div id="navigation">
        
        <a class="nav nav-prev" href="http://shardingjdbc.io/document/legacy/2.x/cn/02-guide/hint-sharding-value/"> <i class="fa fa-chevron-left"></i></a>
        <a class="nav nav-next" href="http://shardingjdbc.io/document/legacy/2.x/cn/02-guide/transaction/" style="margin-right: 0px;"><i class="fa fa-chevron-right"></i></a>
    </div>

    </section>
    <div style="left: -1000px; overflow: scroll; position: absolute; top: -1000px; border: none; box-sizing: content-box; height: 200px; margin: 0px; padding: 0px; width: 200px;">
      <div style="border: none; box-sizing: content-box; height: 200px; margin: 0px; padding: 0px; width: 200px;"></div>
    </div>
    <script src="http://ovfotjrsi.bkt.clouddn.com/docs/js/clipboard.min.js"></script>
    <script src="http://ovfotjrsi.bkt.clouddn.com/docs/js/perfect-scrollbar.min.js"></script>
    <script src="http://ovfotjrsi.bkt.clouddn.com/docs/js/perfect-scrollbar.jquery.min.js"></script>
    <script src="http://ovfotjrsi.bkt.clouddn.com/docs/js/jquery.sticky-kit.min.js"></script>
    <script src="http://ovfotjrsi.bkt.clouddn.com/docs/js/featherlight.min.js"></script>
    <script src="http://ovfotjrsi.bkt.clouddn.com/docs/js/html5shiv-printshiv.min.js"></script>
    <script src="http://ovfotjrsi.bkt.clouddn.com/docs/js/highlight.pack.js"></script>
    <script>hljs.initHighlightingOnLoad();</script>
    <script src="http://ovfotjrsi.bkt.clouddn.com/docs/js/learn.js"></script>
    <script src="http://ovfotjrsi.bkt.clouddn.com/docs/js/hugo-learn.js"></script>
    <script src="http://cdn.bootcss.com/highlight.js/9.8.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>

  </body>
</html>

